import http from 'http';
import url from 'url';
import { createHttpRequest, createHttpResponse, createHttpTransaction, generateId } from '../types/index.js';
import { ProxyUtils } from './utils.js';

/**
 * HTTP请求处理器
 * 负责处理HTTP代理请求
 */
export class HttpHandler {
  constructor(database, ruleEngine, webSocketServer, connectionManager) {
    this.database = database;
    this.ruleEngine = ruleEngine;
    this.webSocketServer = webSocketServer;
    this.connectionManager = connectionManager;
  }

  /**
   * 处理HTTP请求
   */
  async handleHttpRequest(req, res) {
    const startTime = Date.now();
    const transactionId = generateId();

    try {
      console.log(`📨 HTTP请求: ${req.method} ${req.url}`);

      // 跳过系统测试请求
      if (this.connectionManager.isSystemTestRequest(req.url)) {
        console.log(`⚠️ 跳过系统测试请求: ${req.url}`);
        res.writeHead(204);
        res.end();
        return;
      }

      // 提取请求数据
      const requestData = await ProxyUtils.extractRequestData(req, false);
      requestData.id = transactionId;

      // 读取请求体
      const body = await ProxyUtils.readRequestBody(req);
      requestData.body = body;

      // 解析目标URL
      const targetUrl = new URL(req.url);
      const options = {
        hostname: targetUrl.hostname,
        port: targetUrl.port || 80,
        path: targetUrl.pathname + (targetUrl.search || ''),
        method: req.method,
        headers: ProxyUtils.cleanProxyHeaders(req.headers)
      };

      console.log(`🔄 转发请求到: ${targetUrl.hostname}${options.path}`);

      // 发起代理请求
      const proxyReq = http.request(options, (proxyRes) => {
        this.handleProxyResponse(proxyRes, res, requestData, startTime, transactionId);
      });

      proxyReq.on('error', (error) => {
        console.error(`❌ HTTP代理请求失败:`, error.message);
        this.recordFailedRequest(requestData, startTime, transactionId, error);
        if (!res.headersSent) {
          res.writeHead(502, { 'Content-Type': 'text/plain' });
          res.end('代理请求失败');
        }
      });

      // 转发请求体
      if (body) {
        proxyReq.write(body);
      }
      proxyReq.end();

    } catch (error) {
      console.error(`❌ 处理HTTP请求失败:`, error.message);
      if (!res.headersSent) {
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('内部服务器错误');
      }
    }
  }

  /**
   * 处理代理响应
   */
  async handleProxyResponse(proxyRes, res, requestData, startTime, transactionId) {
    try {
      console.log(`✅ 收到响应: ${proxyRes.statusCode} ${proxyRes.statusMessage}`);

      // 转发状态码和响应头
      res.writeHead(proxyRes.statusCode, proxyRes.headers);

      let responseBody = '';
      let responseBodyBuffer = Buffer.alloc(0);

      // 转发响应体并收集数据
      proxyRes.on('data', (chunk) => {
        responseBodyBuffer = Buffer.concat([responseBodyBuffer, chunk]);
        res.write(chunk);
      });

      proxyRes.on('end', async () => {
        const endTime = Date.now();
        console.log(`🏁 响应传输完成: ${responseBodyBuffer.length} bytes`);

        res.end();

        // 解压响应内容
        const contentEncoding = proxyRes.headers['content-encoding'];
        const contentType = proxyRes.headers['content-type'] || '';

        try {
          if (ProxyUtils.isTextContent(contentType)) {
            responseBody = await ProxyUtils.decompressResponseBody(responseBodyBuffer, contentEncoding);
          } else {
            responseBody = `[Binary data: ${responseBodyBuffer.length} bytes]`;
          }
        } catch (error) {
          console.warn('⚠️ 处理响应体失败:', error.message);
          responseBody = `[Binary data: ${responseBodyBuffer.length} bytes]`;
        }

        // 记录事务
        await this.recordTransaction(requestData, proxyRes, responseBody, responseBodyBuffer.length, startTime, endTime, transactionId);
      });

      proxyRes.on('error', (error) => {
        console.error(`❌ 接收响应失败:`, error.message);
        if (!res.headersSent) {
          res.writeHead(502);
          res.end('响应接收失败');
        }
      });

    } catch (error) {
      console.error(`❌ 处理代理响应失败:`, error.message);
    }
  }

  /**
   * 记录失败的请求
   */
  recordFailedRequest(requestData, startTime, transactionId, error) {
    try {
      const endTime = Date.now();
      const duration = endTime - startTime;

      const httpRequest = createHttpRequest({
        ...requestData,
        id: transactionId,
        timestamp: startTime
      });

      const httpResponse = createHttpResponse({
        id: `${transactionId}-response`,
        requestId: transactionId,
        statusCode: 0,
        headers: {},
        cookies: {},
        body: `请求失败: ${error.message}`,
        bodySize: 0,
        timestamp: endTime
      });

      const transaction = createHttpTransaction({
        id: transactionId,
        request: httpRequest,
        response: httpResponse,
        duration,
        createdAt: startTime,
        error: error.message
      });

      // 保存到数据库
      this.database.saveTransaction(transaction);

      // 通过WebSocket实时推送
      if (this.webSocketServer) {
        this.webSocketServer.broadcastTransaction(transaction);
      }

    } catch (recordError) {
      console.error('❌ 记录失败请求时出错:', recordError.message);
    }
  }

  /**
   * 记录完整事务
   */
  async recordTransaction(requestData, proxyRes, responseBody, bodySize, startTime, endTime, transactionId) {
    try {
      const duration = endTime - startTime;

      const httpRequest = createHttpRequest({
        ...requestData,
        id: transactionId,
        timestamp: startTime
      });

      const httpResponse = createHttpResponse({
        id: `${transactionId}-response`,
        requestId: transactionId,
        statusCode: proxyRes.statusCode,
        headers: proxyRes.headers,
        cookies: ProxyUtils.extractCookies(proxyRes.headers),
        body: responseBody,
        bodySize: bodySize,
        timestamp: endTime
      });

      const transaction = createHttpTransaction({
        id: transactionId,
        request: httpRequest,
        response: httpResponse,
        duration,
        createdAt: startTime
      });

      // 保存到数据库
      this.database.saveTransaction(transaction);

      // 通过WebSocket实时推送
      if (this.webSocketServer) {
        this.webSocketServer.broadcastTransaction(transaction);
      }

      // 执行规则匹配
      if (this.ruleEngine) {
        this.ruleEngine.processTransaction(transaction);
      }

      console.log(`📡 广播事务: ${requestData.method} ${requestData.url}`);

    } catch (error) {
      console.error('❌ 记录事务时出错:', error.message);
    }
  }
} 